被替換為子類,也不會影響其運作。參考 設計模式 禪的解說,因應此原則,父子 class 會有一些「限制」:參數輸入和回傳型別
string | number,子 class 只能接受 string,那麼在主程序傳入 number ,替換為子 class 就型別報錯,出事情了!string | number,替換為回傳 string 的子 class ,不會有問題。class
子類
type State = Record<string, any>;
interface BasicState {
    state: State;
    getState(): State;
}
interface MemberStateObj extends State {
    account: string;
}
class MemberState implements BasicState {
    state: MemberStateObj;
    constructor(state: MemberStateObj) {
        this.state = state;
    }
    getState() {
        return this.state;
    }
}
interface OrderStateObj extends State {
    items: any[];
    transportation: number;
}
class OrderState implements BasicState {
    state: OrderStateObj;
    constructor(state: OrderStateObj) {
        this.state = state;
    }
    getState() {
        return this.state;
    }
}
使用子類的class
class StateManager {
    stateHolder: BasicState;
    constructor(stateHolder: BasicState) {
        this.stateHolder = stateHolder;
    }
    getStateKeys() {
        return Object.keys(this.stateHolder.getState());
    }
}
const stateManager = new StateManager(
    new MemberState({
        account: 'aaa111',
    })
);
stateManager.getStateKeys(); // [ 'account' ]
stateManager.stateHolder = new OrderState({
    items: [],
    transportation: 20,
});
stateManager.getStateKeys(); // [ 'items', 'transportation' ]
function
子類function
function calc(calcFn: Function, ...nums: number[]): number {
    return calcFn(nums);
}
function calcSumV2(...nums: number[]): number {
    return calc((_nums: number[]) => _nums.reduce((p, n) => p + n, 0), ...nums);
}
function calcMutiply(...nums: number[]): number {
    return calc((_nums: number[]) => _nums.reduce((p, n) => p * n, 1), ...nums);
}
Calculator
function Calculator(
    this: {
        calcFn: (...nums: number[]) => number;
        getResult: Function;
    },
    calcFn: (...nums: number[]) => number,
    ...nums: number[]
) {
    this.calcFn = calcFn;
    this.getResult = () => this.calcFn(...nums);
    return this;
}
const _calculator = new (Calculator as any)(calcSumV2, 1, 2, 3, 4, 5);
_calculator.getResult(); // 15(1+2+3...)
_calculator.calcFn = calcMutiply;
_calculator.getResult(); // 120(1*2*3...)